#include "SehnsuchtPrecompiled.hxx"
#include "SehnsuchtBasicRenderTarget.hxx"

void Sehnsucht::BasicRenderTarget::CreateDeviceIndependentResources(_No_args_)
{
}

void Sehnsucht::BasicRenderTarget::UpdateForWindowSizeChange(_No_args_)
{
}

void Sehnsucht::BasicRenderTarget::CreateDeviceResources(_No_args_)
{
}

Sehnsucht::BasicRenderTarget::BasicRenderTarget(_No_args_) :
	m_width(0), m_height(0)
{
	m_clear = Reign::Color(0.05f, 0.05f, 0.05f, 1.0f);
	ZeroValue(&m_viewport);
}

void Sehnsucht::BasicRenderTarget::Initialize(_No_args_)
{
	CreateDeviceIndependentResources();
	CreateDeviceResources();
	CreateWindowSizeDependentResources();
}

void Sehnsucht::BasicRenderTarget::CreateWindowSizeDependentResources(_No_args_)
{
	D3D11_TEXTURE2D_DESC textureDesc;
	ZeroValue(&textureDesc);

	// Setup the render target texture description.
	textureDesc.Width = _To_uint Width();
	textureDesc.Height = _To_uint Height();
	textureDesc.MipLevels = 1;
	textureDesc.ArraySize = 1;
	textureDesc.SampleDesc.Count = 1;
	textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	//textureDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	textureDesc.Usage = D3D11_USAGE_DEFAULT;
	textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
	textureDesc.CPUAccessFlags = 0;
	textureDesc.MiscFlags = 0;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateTexture2D(&textureDesc, nullptr, m_d3dRenderTarget.GetAddressOf()));

	D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
	ZeroValue(&renderTargetViewDesc);

	// Setup the description of the render target view.
	renderTargetViewDesc.Format = textureDesc.Format;
	renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
	renderTargetViewDesc.Texture2D.MipSlice = 0;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateRenderTargetView(
		m_d3dRenderTarget.Get(), &renderTargetViewDesc, 
		m_d3dRenderTargetView.GetAddressOf())
		);

	D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
	ZeroValue(&shaderResourceViewDesc);

	// Setup the description of the shader resource view.
	shaderResourceViewDesc.Format = textureDesc.Format;
	shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
	shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
	shaderResourceViewDesc.Texture2D.MipLevels = 1;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateShaderResourceView(
		m_d3dRenderTarget.Get(), &shaderResourceViewDesc, 
		m_d3dShaderResourceView.GetAddressOf())
		);

	D3D11_UNORDERED_ACCESS_VIEW_DESC unorderedAccessViewDesc;
	ZeroValue(&unorderedAccessViewDesc);

	// Setup the description of the unoredered access view.
	unorderedAccessViewDesc.Format = textureDesc.Format;
	unorderedAccessViewDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateUnorderedAccessView(
		m_d3dRenderTarget.Get(), &unorderedAccessViewDesc, 
		m_d3dUnorderedAccessView.GetAddressOf())
		);

	D3D11_TEXTURE2D_DESC depthBufferDesc;
	ZeroValue(&depthBufferDesc);

	// Set up the description of the depth buffer.
	depthBufferDesc.Width = _To_uint Width();
	depthBufferDesc.Height = _To_uint Height();
	depthBufferDesc.MipLevels = 1;
	depthBufferDesc.ArraySize = 1;
	depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthBufferDesc.SampleDesc.Count = 1;
	depthBufferDesc.SampleDesc.Quality = 0;
	depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
	depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthBufferDesc.CPUAccessFlags = 0;
	depthBufferDesc.MiscFlags = 0;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateTexture2D(
		&depthBufferDesc, nullptr, 
		m_d3dDepthStencil.GetAddressOf())
		);

	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	ZeroValue(&depthStencilViewDesc);

	// Set up the depth stencil view description.
	depthStencilViewDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	Sehnsucht::ThrowIfFailed(m_d3dDevice->CreateDepthStencilView(
		m_d3dDepthStencil.Get(), &depthStencilViewDesc, 
		m_d3dDepthStencilView.GetAddressOf())
		);

	m_viewport.Width = Width();
	m_viewport.Height = Height();
	m_viewport.MinDepth = 0.0f;
	m_viewport.MaxDepth = 1.0f;
	m_viewport.TopLeftX = 0.0f;
	m_viewport.TopLeftY = 0.0f;
}


